﻿namespace System.Data.Entity.Extensions.UnitOfWork
{
    /// <summary>
    /// 
    /// </summary>
    public class DbContextUnitOfWorkFactory : IUnitOfWorkFactory
    {        
        #region Constructor 

        /// <summary>
        /// 
        /// </summary>
        /// <param name="contextDelegate"></param>
        public DbContextUnitOfWorkFactory(Func<DbContext> contextDelegate)
        {
            DbContextUnitOfWorkFactory._contextDelegate = contextDelegate;
        }
        
        #endregion

        #region IDisposable Implementation

        private bool _disposed;

        /// <summary>
        /// 
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="disposing"></param>
        protected virtual void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (disposing)
                {

                }

                _disposed = true;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        ~DbContextUnitOfWorkFactory()
        {
            Dispose(false);
        }

        #endregion

        #region DbContext
                        
        /// <summary>
        /// 
        /// </summary>
        private static Func<DbContext> _contextDelegate;

        /// <summary>
        /// 
        /// </summary>
        private static readonly object _lock = new object();
                        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="contextDelegate"></param>
        public static void SetDbContext(Func<DbContext> contextDelegate)
        {
            DbContextUnitOfWorkFactory._contextDelegate = contextDelegate;
        }

        #endregion

        #region IUnitOfWorkFactory Implementation

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public virtual IUnitOfWork Create()
        {
            DbContext context;

            lock (DbContextUnitOfWorkFactory._lock)
            {
                context = DbContextUnitOfWorkFactory._contextDelegate();
            }
            
            return new DbContextUnitOfWork(context);
        }
        
        #endregion
    }
}
